<?php
/**
 * 后台基类
 * @author yupoxiong<i@yupoxiong.com>
 */

declare (strict_types=1);

namespace app\admin\controller;

use think\db\exception\{ModelNotFoundException,DataNotFoundException,DbException};
use app\admin\traits\{AdminPhpOffice, AdminTreeTrait};
use app\admin\model\{AdminMenu, AdminUser};
use app\admin\service\AdminLogService;
use app\common\model\CommonBaseModel;
use support\Response;
use taoser\Validate;
use support\View;

class AdminBaseController
{
    // 引入树相关trait
    use AdminTreeTrait;

    // 引入office相关trait
    use AdminPhpOffice;

    /**
     * 后台主变量
     * @var array
     */
    protected array $admin;

    /**
     * 当前访问的URL
     * @var string
     */
    protected string $url;

    /**
     * 当前访问的菜单
     * @var mixed
     */
    protected $menu;

    protected CommonBaseModel $model;

    protected Validate $validate;

    public function __construct()
    {
        $this->url = request()->request_url;
        // 初始化
        $this->initialize();
    }

    /**
     * 初始化方法
     */
    public function initialize(): void
    {
        // 分页每页数量
        $this->admin['admin_list_rows'] = (int)((request())->cookie('admin_list_rows') ?? 10);
        // 限制每页数量最多不超过100
        $this->admin['admin_list_rows'] = $this->admin['admin_list_rows'] < 100 ? $this->admin['admin_list_rows'] : 100;
        /** @var AdminMenu $menu */
        $this->menu = (new AdminMenu)->where(['url' => $this->url])->findOrEmpty();

        if (isset((request())->user) && !$this->menu->isEmpty() && (request())->method() === $this->menu->log_method) {
            // 如果用户登录了而且符合菜单记录日志方式，记录操作日志
            (new AdminLogService())->createLog((request())->user, $this->menu->name);
        }
    }

    /**
     * 渲染模板
     * @param string $template
     * @param array $vars
     * @return Response
     */
    protected function fetch(string $template = '', array $vars = []): Response
    {
        if (empty($template)) {
            $template = substr($this->url, 6);
        } elseif (strpos($template, '/') === false) {
            $url_str  = substr($this->url, 6);
            $url_arr  = explode('/', $url_str);
            $template = $url_arr[0] . '/' . $template;
        }

        // 顶部导航
        $this->admin['top_nav'] = (int)setting('admin.display.top_nav');
        // 后台基本信息配置
        $this->admin['base'] = setting('admin.base');
        // 当前顶部导航ID
        $current_top_id = 0;

        if (!$this->menu->isEmpty()) {
            $menu = $this->menu;
            try {
                $menu_all = (new AdminMenu)->field('id,parent_id,name,icon')->select()->toArray();
                // 当前面包屑
                $this->admin['breadcrumb'] = $this->getBreadCrumb($menu_all, $menu->id);
                if ($this->admin['top_nav'] === 1) {
                    // 顶部导航id
                    $current_top_id = $this->getTopParentIdById($menu_all, $menu->id);
                }
            } catch (DataNotFoundException | ModelNotFoundException | DbException $e) {
                return \response('获取所有菜单失败，参考信息：' . $e->getMessage());
            }
            // 当前页面标题
            $this->admin['title'] = $menu->name;

        }
        // 当前是否为pjax访问
        $this->admin['is_pjax'] = (request())->isPjax();
        // 上传文件url
        $this->admin['upload_url'] = url('admin/file/upload');
        // 退出url
        $this->admin['logout_url'] = url('admin/auth/logout');

        if ('admin/auth/login' !== $this->url && !$this->admin['is_pjax'] && isset(request()->user)) {
            // 展示菜单
            $show_menu = request()->user->getShowMenu($this->admin['top_nav']);
            // 顶部导航
            $this->admin['top_menu'] = $show_menu['top'];
            // 左侧菜单
            $this->admin['left_menu'] = $this->getLeftMenu($show_menu['left'][$current_top_id], $menu->id ?? 0);
        }
        // 是否开启debug
        $this->admin['debug'] = config('app.app_debug') ? 1 : 0;
        // 顶部导航
        $this->admin['top_nav'] = 1;
        // 顶部搜索
        $this->admin['top_search'] = 0;
        // 顶部消息
        $this->admin['top_message'] = 0;
        // 顶部通知
        $this->admin['top_notification'] = 0;
        // 文件删除url
        $this->admin['file_del_url'] = url('admin/file/del');
        // 地图配置
        $this->admin['map'] = config('map');
        // 当前用户
        $this->admin['user'] = request()->user ?? new AdminUser();

        // 赋值后台变量
        $this->assign([
            'admin' => $this->admin,
        ]);

        return view($template, $vars);
    }


    /**
     * 模板赋值
     * @param $name
     * @param null $value
     */
    protected function assign($name, $value = null): void
    {
        View::assign($name, $value);
    }
}
